package com.pangu.web.view;

import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.View;

public abstract class AbstractCachingViewResolver implements ViewResolver {
	protected final Log log = Logs.getLog(getClass());

	private boolean cache = true;

	private ConcurrentMap<String, View> viewCache = new ConcurrentHashMap<String, View>();

	public void setCache(boolean cache) {
		this.cache = cache;
	}

	public boolean isCache() {
		return this.cache;
	}

	protected String getType() {
		return null;
	}

	public View resolveViewName(String viewName, Locale locale)
		throws Exception {
		if (!isCache()) {
			log.warn("View caching is switched off");
			return createView(viewName, locale);
		} else {
			String cacheKey = getCacheKey(viewName);
			View view = this.viewCache.get(cacheKey);
			if (view == null) {
				view = createView(viewName, locale);
				this.viewCache.putIfAbsent(cacheKey, view);
				if (log.isDebugEnabled())
					log.debug("Cached view [" + cacheKey + "]");
			}
			return view;
		}
	}

	protected String getCacheKey(String viewName) {
		return viewName;
	}

	public void removeFromeCache(String viewName) {
		if (!isCache()) {
			log.warn("View caching is switched off, remove noting");
		} else {
			String cacheKey = getCacheKey(viewName);
			View cacheView = null;
			cacheView = this.viewCache.remove(cacheKey);
			if (log.isDebugEnabled()) {
				log.debug(cacheView == null ? "No cached instance for view '"
						+ cacheKey + "' was found" : "Cache for view '"
						+ cacheKey + "' has been cleared");
			}
		}
	}

	public void clearCache() {
		log.debug("Clearing entire view cache");
		this.viewCache.clear();
	}

	public View createView(String name, Locale locale) {
		return loadView(name, locale);
	}

	public abstract View loadView(String viewName, Locale locale);
}
